package com.hj.calendar.client;

import com.github.caldav4j.methods.CalDAV4JMethodFactory;
import com.github.caldav4j.methods.HttpCalDAVReportMethod;
import com.github.caldav4j.methods.HttpPropFindMethod;
import com.github.caldav4j.model.request.*;
import com.github.caldav4j.util.XMLUtils;
import com.hj.calendar.domain.constant.CaldavConfig;
import com.hj.calendar.domain.constant.SymbolConstant;
import com.hj.calendar.domain.dto.CaldavDdFsDTO;
import com.hj.calendar.domain.model.CaldavModel;
import lombok.extern.slf4j.Slf4j;
import net.fortuna.ical4j.model.DateTime;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.jackrabbit.webdav.DavConstants;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.property.DavPropertyName;
import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author hj
 * @Date 2022/5/22
 * @Description: 钉钉caldav的相关操作
 */
@Slf4j
@Component
public class CaldavDdClient {


    /**
     * 获取钉钉日历名称
     *
     * @param dto CaldavDdFsDTO
     * @return displayName
     */
    public String getDdDisplayName(CaldavDdFsDTO dto) {
        HttpClient client = CaldavClient.createHttpClient(dto.getUsername(), dto.getPassword());
        CalDAV4JMethodFactory factory = new CalDAV4JMethodFactory();
        try {
            //
            String url = String.format("https://%s:%s@%s/dav/%s/primary", dto.getUsername(), dto.getPassword(),
                    CaldavConfig.THREE_DD_HOST, dto.getUsername());
            DavPropertyNameSet davPropertyNameSet = new DavPropertyNameSet();
            davPropertyNameSet.add(DavPropertyName.DISPLAYNAME);
            HttpPropFindMethod propFindMethod = factory.createPropFindMethod(url, davPropertyNameSet, DavConstants.DEPTH_0);
            HttpHost hostConfig = new HttpHost(CaldavConfig.THREE_DD_HOST, CaldavConfig.PORT, CaldavConfig.PROTOCOL);
            HttpResponse response = client.execute(hostConfig, propFindMethod);
            String status = response.getStatusLine().toString();
            if (status.contains(SymbolConstant.TWO_ZERO_SEVEN)) {
                // 日历名称
                String displayUrl = String.format("/dav/%s/primary/", dto.getUsername());
                String displayName = propFindMethod.getDisplayName(response, displayUrl);
                log.info(displayName);
                return displayName;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 获取钉钉日程
     *
     * @param dto CaldavFsDTO
     */
    public List<CaldavModel> getCalendar(CaldavDdFsDTO dto) {
        // 处理日期
        CaldavClient.handleFsCaldavDate(dto);
        HttpClient client = CaldavClient.createHttpClient(dto.getUsername(), dto.getPassword());
        CalDAV4JMethodFactory factory = new CalDAV4JMethodFactory();
        try {
            // 查询 过滤 条件
            CompFilter compFilter = new CompFilter(net.fortuna.ical4j.model.Calendar.VCALENDAR);
            compFilter.addCompFilter(new CompFilter(net.fortuna.ical4j.model.Component.VEVENT));
            compFilter.getCompFilters().get(0)
                    .setTimeRange(
                            new TimeRange(
                                    new DateTime(dto.getCaldavStartTime()),
                                    new DateTime(dto.getCaldavEndTime())
                            )
                    );
            DavPropertyNameSet properties = new DavPropertyNameSet();
            properties.add(DavPropertyName.GETETAG);
            CalendarQuery query = new CalendarQuery(properties, compFilter, new CalendarData(), false, false);
            log.info("钉钉日历查询封装的xml:{}", XMLUtils.prettyPrint(query));
            String url = String.format("https://%s:%s@%s/dav/%s/primary/", dto.getUsername(), dto.getPassword(),
                    CaldavConfig.THREE_DD_HOST, dto.getUsername());
            HttpCalDAVReportMethod caldavReportMethod = factory.createCalDAVReportMethod(url, query, DavConstants.DEPTH_1);
            HttpHost hostConfig = new HttpHost(CaldavConfig.THREE_DD_HOST, CaldavConfig.PORT, CaldavConfig.PROTOCOL);
            long a = System.currentTimeMillis();
            log.info("开始调用钉钉日历:{}", a);
            HttpResponse response = client.execute(hostConfig, caldavReportMethod);
            long b = System.currentTimeMillis();
            log.info("结束调用钉钉日历:{},耗时:{}秒", b, (b - a) / 1000);
            String status = response.getStatusLine().toString();
            log.info("\n\n获取钉钉日历-返回的状态信息:{}\n\n", status);
            if (status.contains(SymbolConstant.TWO_ZERO_SEVEN)) {
                // calendar-data
                List<CaldavModel> ddCaldavModelList = new ArrayList<>();
                CaldavClient.handleCalendar(caldavReportMethod, response, ddCaldavModelList);
                return ddCaldavModelList;
            }
        } catch (ParseException | IOException | DavException e) {
            e.printStackTrace();
        }
        return null;
    }


}
